package cn.net.dpi.core.api.vo;

import cn.net.dpi.core.exception.ApiError;
import cn.net.dpi.core.exception.BaseException;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.slf4j.Logger;

import java.io.Serializable;

@Data
@NoArgsConstructor
@AllArgsConstructor
@ApiModel(value="Response对象", description="请求返回的响应")
public class Response<T> implements Serializable {

    @ApiModelProperty(value = "错误码，0为正确")
    private Integer code;

    @ApiModelProperty(value = "错误描述信息")
    private String msg;

    @ApiModelProperty(value = "返回的数据结果对象")
    private T data;

    @ApiModelProperty(value = "时间戳")
    private Long timestamp;


    /**
     * 返回成功对象
     * @return Response - 返回对象
     */
    public static <T> Response<T> success() {
        return new Response<>(ApiError.SUCCESS, null);
    }

    /**
     * 返回成功对象
     * @param data - 数据对象
     * @return Response - 返回对象
     */
    public static <T> Response<T> success(T data) {
        return new Response<>(ApiError.SUCCESS, data);
    }

    /**
     * 返回成功对象
     * @param message - 成功信息
     * @return Response - 返回对象
     */
    public static <T> Response<T> success(String message) {
        return new Response<>(ApiError.SUCCESS.getCode(), message, null);
    }

    /**
     * 返回成功对象
     * @param message - 成功信息
     * @param data - 数据对象
     * @return Response - 返回对象
     */
    public static <T> Response<T> success(String message, T data) {
        return new Response<>(ApiError.SUCCESS.getCode(), message, data);
    }

    /**
     * 返回失败对象
     *
     * @param code - 错误代码
     * @param message - 失败信息
     * @param data - 数据对象
     * @return Response - 返回对象
     */
    public static <T> Response<T> success(Integer code, String message, T data) {
        return new Response<>(code, message, data);
    }
    /**
     * 返回错误对象
     *
     * @param data - 数据对象
     * @return Response - 返回对象
     */
    public static <T> Response<T> error(T data) {
        return Response.fail(data);
    }

    /**
     * 返回错误对象
     *
     * @param err - 错误对象
     * @return Response - 返回对象
     */
    public static <T> Response<T> error(ApiError err) {
        return Response.fail(err);
    }

    /**
     * 打印错误日志并返回错误对象
     *
     * @param err - 错误对象
     * @param data - 数据对象
     * @param logger - 日志对象
     * @return Response - 返回对象
     */
    public static <T> Response<T> error(ApiError err, Object data, Logger logger) {
        return Response.fail(err, data, logger);
    }

    /**
     * 返回错误对象
     *
     * @return Response - 返回对象
     */
    public static <T> Response<T> error() {
        return Response.fail();
    }

    /**
     * 返回错误对象
     *
     * @param message - 错误信息
     * @return Response - 返回对象
     */
    public static <T> Response<T> error(String message) {
        return Response.fail(message);
    }

    /**
     * 返回错误对象
     *
     * @param error - 错误对象
     * @param data - 数据对象
     * @return Response - 返回对象
     */
    public static <T> Response<T> error(ApiError error, T data) {
        return Response.fail(error, data);
    }

    /**
     * 返回错误对象
     *
     * @param ex - 异常
     * @param data - 数据对象
     * @return Response - 返回对象
     */
    public static <T> Response<T> error(BaseException ex, T data) {
        return Response.fail(ex, data);
    }

    /**
     * 返回错误对象
     *
     * @param code - 错误代码
     * @param message - 错误信息
     * @param data - 数据对象
     * @return Response - 返回对象
     */
    public static <T> Response<T> error(Integer code, String message, T data) {
        return Response.fail(code, message, data);
    }

    /**
     * 返回失败对象
     *
     * @param data - 数据对象
     * @return Response - 返回对象
     */
    public static <T> Response<T> fail(T data) {
        return new Response<>(ApiError.FAIL, data);
    }

    /**
     * 返回错误对象
     *
     * @param err - 错误对象
     * @return Response - 返回对象
     */
    public static <T> Response<T> fail(ApiError err) {
        return new Response<>(err, null);
    }

    /**
     * 打印错误日志并返回错误对象
     *
     * @param err - 错误对象
     * @param data - 数据对象
     * @param logger - 日志对象
     * @return Response - 返回对象
     */
    public static <T> Response<T> fail(ApiError err, Object data, Logger logger) {
        logger.warn("[code:{}], [message:{}], [data:{}]", err.getCode(), err.getMessage(), data);
        return new Response<>(err, null);
    }

    /**
     * 返回失败对象
     *
     * @return Response - 返回对象
     */
    public static <T> Response<T> fail() {
        return new Response<>(ApiError.FAIL, null);
    }

    /**
     * 返回失败对象
     *
     * @param message - 失败信息
     * @return Response - 返回对象
     */
    public static <T> Response<T> fail(String message) {
        return new Response<>(ApiError.FAIL.getCode(), message, null);
    }

    /**
     * 返回失败对象
     *
     * @param error - 错误对象
     * @param data - 数据对象
     * @return Response - 返回对象
     */
    public static <T> Response<T> fail(ApiError error, T data) {
        return new Response<>(error, data);
    }

    /**
     * 返回失败对象
     *
     * @param ex - 异常
     * @param data - 数据对象
     * @return Response - 返回对象
     */
    public static <T> Response<T> fail(BaseException ex, T data) {
        return new Response<>(ex.getError(), data);
    }

    /**
     * 返回失败对象
     *
     * @param code - 错误代码
     * @param message - 失败信息
     * @param data - 数据对象
     * @return Response - 返回对象
     */
    public static <T> Response<T> fail(Integer code, String message, T data) {
        return new Response<>(code, message, data);
    }

    private Response(ApiError error, T data) {
        this.code = error.getCode();
        this.msg = error.getMessage();
        this.data = data;
        this.timestamp = System.currentTimeMillis();
    }

    private Response(Integer code, String message, T data) {
        this.code = code;
        this.msg = message;
        this.data = data;
        this.timestamp = System.currentTimeMillis();
    }

}
